<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>动态文字弹幕系统</title>
  <!-- 引入Tailwind CSS -->
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- 引入Font Awesome -->
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  
  <!-- 配置Tailwind自定义颜色和字体 -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#3B82F6',
            secondary: '#EC4899',
            dark: '#1E293B',
            light: '#F8FAFC'
          },
          fontFamily: {
            sans: ['Inter', 'system-ui', 'sans-serif'],
          },
        },
      }
    }
  </script>
  
  <!-- 自定义工具类 -->
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .text-shadow {
        text-shadow: 0 2px 4px rgba(0,0,0,0.1);
      }
      .backdrop-blur {
        backdrop-filter: blur(8px);
      }
    }
  </style>
  
  <style>
    /* 弹幕容器和动画 */
    .danmaku-container {
      position: relative;
      overflow: hidden;
      height: 70vh;
      background: linear-gradient(135deg, #0F172A 0%, #1E293B 100%);
    }
    
    .danmaku {
      position: absolute;
      white-space: nowrap;
      cursor: pointer;
      animation-timing-function: linear;
      will-change: transform;
      z-index: 10;
    }
    
    /* 自定义滚动条 */
    ::-webkit-scrollbar {
      width: 8px;
      height: 8px;
    }
    
    ::-webkit-scrollbar-track {
      background: #f1f1f1;
      border-radius: 4px;
    }
    
    ::-webkit-scrollbar-thumb {
      background: #c1c1c1;
      border-radius: 4px;
    }
    
    ::-webkit-scrollbar-thumb:hover {
      background: #a1a1a1;
    }
    
    /* 加载动画 */
    @keyframes pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.5; }
    }
    
    .animate-pulse-slow {
      animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
    }
  </style>
</head>
<body class="bg-gray-50 font-sans text-gray-800 min-h-screen flex flex-col">
  <!-- 页面头部 -->
  <header class="bg-gradient-to-r from-primary to-secondary text-white shadow-lg">
    <div class="container mx-auto px-4 py-6">
      <h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold flex items-center justify-center">
        <i class="fa fa-comment-o mr-3 animate-pulse"></i>
        动态文字弹幕系统
      </h1>
      <p class="text-center mt-2 text-white/80 max-w-2xl mx-auto">
        发送你的想法，让它在屏幕上流动起来
      </p>
    </div>
  </header>

  <!-- 主内容区 -->
  <main class="flex-grow container mx-auto px-4 py-6 flex flex-col md:flex-row gap-6">
    <!-- 弹幕显示区域 -->
    <div class="w-full md:w-2/3 rounded-xl overflow-hidden shadow-xl transform transition-all duration-300 hover:shadow-2xl">
      <div class="danmaku-container relative">
        <!-- 示例背景图 -->
        <img src="https://picsum.photos/id/1045/1200/800" alt="弹幕背景图" class="absolute inset-0 w-full h-full object-cover opacity-30">
        
        <!-- 初始提示信息 -->
        <div id="initial-message" class="absolute inset-0 flex flex-col items-center justify-center text-white/70 z-5">
          <i class="fa fa-comment text-5xl mb-4 animate-pulse-slow"></i>
          <p class="text-xl text-center max-w-md px-4">发送你的第一条弹幕吧！</p>
        </div>
      </div>
    </div>
    
    <!-- 控制面板 -->
    <div class="w-full md:w-1/3 bg-white rounded-xl shadow-lg p-6 flex flex-col gap-5">
      <h2 class="text-xl font-bold text-gray-800 border-b pb-3 flex items-center">
        <i class="fa fa-cog text-primary mr-2"></i>弹幕控制
      </h2>
      
      <!-- 发送弹幕表单 -->
      <form id="danmaku-form" class="space-y-4">
        <div>
          <label for="message" class="block text-sm font-medium text-gray-700 mb-1">弹幕内容</label>
          <div class="flex">
            <input 
              type="text" 
              id="message" 
              placeholder="输入你想发送的内容..." 
              required
              maxlength="50"
              class="flex-grow px-4 py-2 border border-gray-300 rounded-l-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all outline-none"
            >
            <button 
              type="submit" 
              class="bg-primary hover:bg-primary/90 text-white px-4 py-2 rounded-r-lg transition-all transform hover:scale-105 active:scale-95 flex items-center"
            >
              <i class="fa fa-paper-plane mr-1"></i> 发送
            </button>
          </div>
        </div>
        
        <!-- 颜色选择 -->
        <div>
          <label class="block text-sm font-medium text-gray-700 mb-2">文字颜色</label>
          <div class="flex flex-wrap gap-2">
            <button 
              type="button" 
              class="color-option w-8 h-8 rounded-full bg-white border-2 border-gray-300 hover:scale-110 transition-transform active"
              data-color="#FFFFFF"
            ></button>
            <button 
              type="button" 
              class="color-option w-8 h-8 rounded-full bg-red-500 hover:scale-110 transition-transform"
              data-color="#EF4444"
            ></button>
            <button 
              type="button" 
              class="color-option w-8 h-8 rounded-full bg-yellow-400 hover:scale-110 transition-transform"
              data-color="#FBBF24"
            ></button>
            <button 
              type="button" 
              class="color-option w-8 h-8 rounded-full bg-green-500 hover:scale-110 transition-transform"
              data-color="#22C55E"
            ></button>
            <button 
              type="button" 
              class="color-option w-8 h-8 rounded-full bg-blue-500 hover:scale-110 transition-transform"
              data-color="#3B82F6"
            ></button>
            <button 
              type="button" 
              class="color-option w-8 h-8 rounded-full bg-purple-500 hover:scale-110 transition-transform"
              data-color="#A855F7"
            ></button>
            <button 
              type="button" 
              class="color-option w-8 h-8 rounded-full bg-pink-500 hover:scale-110 transition-transform"
              data-color="#EC4899"
            ></button>
            <input 
              type="color" 
              id="custom-color" 
              class="w-8 h-8 rounded-full p-0 border-0 cursor-pointer hover:scale-110 transition-transform"
              value="#FFFFFF"
            >
          </div>
        </div>
        
        <!-- 字体大小 -->
        <div>
          <label for="font-size" class="block text-sm font-medium text-gray-700 mb-1">
            字体大小: <span id="font-size-value">20</span>px
          </label>
          <input 
            type="range" 
            id="font-size" 
            min="12" 
            max="36" 
            value="20" 
            class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary"
          >
        </div>
        
        <!-- 弹幕速度 -->
        <div>
          <label for="speed" class="block text-sm font-medium text-gray-700 mb-1">
            滚动速度: <span id="speed-value">中等</span>
          </label>
          <input 
            type="range" 
            id="speed" 
            min="5" 
            max="20" 
            value="10" 
            class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary"
          >
          <div class="flex justify-between text-xs text-gray-500 mt-1">
            <span>慢速</span>
            <span>快速</span>
          </div>
        </div>
      </form>
      
      <!-- 操作按钮 -->
      <div class="flex gap-3 mt-4">
        <button id="clear-all" class="flex-1 bg-gray-200 hover:bg-gray-300 text-gray-800 py-2 px-4 rounded-lg transition-all flex items-center justify-center">
          <i class="fa fa-trash mr-2"></i> 清空弹幕
        </button>
        <button id="pause-all" class="flex-1 bg-gray-200 hover:bg-gray-300 text-gray-800 py-2 px-4 rounded-lg transition-all flex items-center justify-center">
          <i class="fa fa-pause mr-2"></i> 暂停/播放
        </button>
      </div>
      
      <!-- 历史记录 -->
      <div class="mt-6">
        <h3 class="text-sm font-medium text-gray-700 mb-2 flex items-center">
          <i class="fa fa-history text-primary mr-1"></i> 最近弹幕
        </h3>
        <div id="history-list" class="max-h-40 overflow-y-auto text-sm space-y-1 text-gray-600">
          <!-- 历史记录将在这里显示 -->
          <p class="text-gray-400 italic text-center text-xs py-4">暂无弹幕记录</p>
        </div>
      </div>
    </div>
  </main>

  <!-- 页脚 -->
  <footer class="bg-dark text-white/70 py-6">
    <div class="container mx-auto px-4 text-center text-sm">
      <p>动态文字弹幕系统 &copy; 2023</p>
      <p class="mt-1">使用 HTML, Tailwind CSS 和 JavaScript 构建</p>
    </div>
  </footer>

  <script>
    // DOM元素
    const danmakuContainer = document.querySelector('.danmaku-container');
    const danmakuForm = document.getElementById('danmaku-form');
    const messageInput = document.getElementById('message');
    const fontSizeInput = document.getElementById('font-size');
    const fontSizeValue = document.getElementById('font-size-value');
    const speedInput = document.getElementById('speed');
    const speedValue = document.getElementById('speed-value');
    const colorOptions = document.querySelectorAll('.color-option');
    const customColorInput = document.getElementById('custom-color');
    const clearAllBtn = document.getElementById('clear-all');
    const pauseAllBtn = document.getElementById('pause-all');
    const historyList = document.getElementById('history-list');
    const initialMessage = document.getElementById('initial-message');
    
    // 状态变量
    let currentColor = '#FFFFFF';
    let isPaused = false;
    let danmakus = [];
    let speedTextMap = {
      5: '极慢',
      6: '很慢',
      7: '较慢',
      8: '慢速',
      9: '偏慢',
      10: '中等',
      11: '偏快',
      12: '快速',
      13: '较快',
      14: '很快',
      15: '极快',
      16: '极快',
      17: '极快',
      18: '极快',
      19: '极快',
      20: '极快'
    };
    
    // 更新显示值
    fontSizeInput.addEventListener('input', () => {
      fontSizeValue.textContent = fontSizeInput.value;
    });
    
    speedInput.addEventListener('input', () => {
      speedValue.textContent = speedTextMap[speedInput.value] || '自定义';
    });
    
    // 颜色选择
    colorOptions.forEach(option => {
      option.addEventListener('click', (e) => {
        e.preventDefault();
        
        // 移除其他选项的active类
        colorOptions.forEach(opt => opt.classList.remove('active', 'ring-2', 'ring-offset-2', 'ring-primary'));
        
        // 添加当前选项的active类
        option.classList.add('active', 'ring-2', 'ring-offset-2', 'ring-primary');
        
        // 更新当前颜色
        currentColor = option.getAttribute('data-color');
        customColorInput.value = currentColor;
      });
    });
    
    // 自定义颜色选择
    customColorInput.addEventListener('input', () => {
      currentColor = customColorInput.value;
      
      // 移除其他选项的active类
      colorOptions.forEach(opt => opt.classList.remove('active', 'ring-2', 'ring-offset-2', 'ring-primary'));
      
      // 检查是否有匹配的预设颜色
      let matched = false;
      colorOptions.forEach(option => {
        if (option.getAttribute('data-color') === currentColor) {
          option.classList.add('active', 'ring-2', 'ring-offset-2', 'ring-primary');
          matched = true;
        }
      });
      
      // 如果没有匹配的预设颜色，添加一个临时的active状态指示
      if (!matched) {
        customColorInput.classList.add('ring-2', 'ring-offset-2', 'ring-primary');
      } else {
        customColorInput.classList.remove('ring-2', 'ring-offset-2', 'ring-primary');
      }
    });
    
    // 发送弹幕
    danmakuForm.addEventListener('submit', (e) => {
      e.preventDefault();
      
      const message = messageInput.value.trim();
      if (!message) return;
      
      const fontSize = parseInt(fontSizeInput.value);
      const speed = parseInt(speedInput.value);
      
      // 创建弹幕
      createDanmaku(message, fontSize, currentColor, speed);
      
      // 添加到历史记录
      addToHistory(message, currentColor);
      
      // 清空输入框
      messageInput.value = '';
      
      // 隐藏初始提示
      if (initialMessage && !initialMessage.classList.contains('hidden')) {
        initialMessage.classList.add('hidden');
      }
      
      // 聚焦输入框
      messageInput.focus();
    });
    
    // 创建弹幕元素并添加动画
    function createDanmaku(text, fontSize, color, speed) {
      const danmaku = document.createElement('div');
      danmaku.className = 'danmaku text-shadow transition-all duration-300 hover:scale-105';
      danmaku.textContent = text;
      danmaku.style.color = color;
      danmaku.style.fontSize = `${fontSize}px`;
      
      // 随机垂直位置，但确保在容器内
      const containerHeight = danmakuContainer.clientHeight;
      const maxTop = containerHeight - fontSize - 20; // 留出一些余量
      const top = Math.floor(Math.random() * maxTop);
      danmaku.style.top = `${top}px`;
      
      // 设置初始位置（容器右侧外面）
      danmaku.style.right = `-${danmaku.offsetWidth}px`;
      
      // 添加到容器
      danmakuContainer.appendChild(danmaku);
      
      // 计算动画持续时间（速度值越大，持续时间越短，弹幕越快）
      const duration = (20 - speed + 1) * 0.8; // 5-20 映射到 13-1.6 秒
      
      // 获取容器宽度和弹幕宽度以计算动画距离
      const containerWidth = danmakuContainer.clientWidth;
      const danmakuWidth = danmaku.offsetWidth;
      const totalDistance = containerWidth + danmakuWidth;
      
      // 设置动画
      danmaku.style.animation = `none`;
      // 强制重绘
      void danmaku.offsetWidth;
      
      // 记录动画开始时间和持续时间，用于暂停/播放功能
      const startTime = Date.now();
      const animationDuration = duration * 1000;
      
      // 存储弹幕信息
      const danmakuInfo = {
        element: danmaku,
        startTime,
        animationDuration,
        totalDistance,
        pausedAt: null,
        isPaused: false
      };
      
      danmakus.push(danmakuInfo);
      
      // 开始动画
      animateDanmaku(danmakuInfo);
      
      // 点击弹幕暂停/继续单个弹幕
      danmaku.addEventListener('click', () => {
        if (danmakuInfo.isPaused) {
          // 继续动画
          danmakuInfo.isPaused = false;
          danmakuInfo.startTime = Date.now() - (danmakuInfo.pausedAt - danmakuInfo.startTime);
          animateDanmaku(danmakuInfo);
          danmaku.style.opacity = '1';
        } else {
          // 暂停动画
          danmakuInfo.isPaused = true;
          danmakuInfo.pausedAt = Date.now();
          cancelAnimationFrame(danmakuInfo.animationFrame);
          danmaku.style.opacity = '0.7';
        }
      });
    }
    
    // 弹幕动画函数
    function animateDanmaku(danmakuInfo) {
      if (danmakuInfo.isPaused || isPaused) {
        return;
      }
      
      const currentTime = Date.now();
      const elapsedTime = currentTime - danmakuInfo.startTime;
      const progress = Math.min(elapsedTime / danmakuInfo.animationDuration, 1);
      const position = -progress * danmakuInfo.totalDistance;
      
      // 更新位置
      danmakuInfo.element.style.transform = `translateX(${position}px)`;
      
      // 检查动画是否完成
      if (progress < 1) {
        // 继续动画
        danmakuInfo.animationFrame = requestAnimationFrame(() => animateDanmaku(danmakuInfo));
      } else {
        // 动画完成，移除元素
        removeDanmaku(danmakuInfo);
      }
    }
    
    // 移除弹幕
    function removeDanmaku(danmakuInfo) {
      // 从数组中移除
      const index = danmakus.indexOf(danmakuInfo);
      if (index !== -1) {
        danmakus.splice(index, 1);
      }
      
      // 从DOM中移除
      if (danmakuInfo.element && danmakuInfo.element.parentNode) {
        // 添加淡出动画
        danmakuInfo.element.style.transition = 'opacity 0.3s ease-out';
        danmakuInfo.element.style.opacity = '0';
        
        // 延迟后移除元素
        setTimeout(() => {
          if (danmakuInfo.element && danmakuInfo.element.parentNode) {
            danmakuInfo.element.parentNode.removeChild(danmakuInfo.element);
          }
          
          // 如果没有弹幕了，显示初始提示
          if (danmakus.length === 0 && initialMessage) {
            initialMessage.classList.remove('hidden');
          }
        }, 300);
      }
    }
    
    // 添加到历史记录
    function addToHistory(text, color) {
      const historyItem = document.createElement('div');
      historyItem.className = 'p-2 bg-gray-50 rounded hover:bg-gray-100 transition-colors';
      historyItem.innerHTML = `
        <div class="flex items-center">
          <span class="inline-block w-3 h-3 rounded-full mr-2" style="background-color: ${color};"></span>
          <span>${text}</span>
        </div>
      `;
      
      // 添加到历史列表顶部
      if (historyList.firstChild && historyList.firstChild.tagName === 'P') {
        historyList.innerHTML = '';
      }
      historyList.insertBefore(historyItem, historyList.firstChild);
      
      // 限制历史记录数量
      if (historyList.children.length > 10) {
        historyList.removeChild(historyList.lastChild);
      }
    }
    
    // 清空所有弹幕
    clearAllBtn.addEventListener('click', () => {
      // 停止所有动画并移除元素
      danmakus.forEach(danmakuInfo => {
        if (danmakuInfo.animationFrame) {
          cancelAnimationFrame(danmakuInfo.animationFrame);
        }
        if (danmakuInfo.element && danmakuInfo.element.parentNode) {
          danmakuInfo.element.parentNode.removeChild(danmakuInfo.element);
        }
      });
      
      // 清空数组
      danmakus = [];
      
      // 显示初始提示
      if (initialMessage) {
        initialMessage.classList.remove('hidden');
      }
      
      // 清空历史记录
      historyList.innerHTML = '<p class="text-gray-400 italic text-center text-xs py-4">暂无弹幕记录</p>';
      
      // 添加按钮动画
      clearAllBtn.classList.add('scale-95');
      setTimeout(() => clearAllBtn.classList.remove('scale-95'), 150);
    });
    
    // 暂停/播放所有弹幕
    pauseAllBtn.addEventListener('click', () => {
      isPaused = !isPaused;
      
      if (isPaused) {
        // 暂停所有弹幕
        pauseAllBtn.innerHTML = '<i class="fa fa-play mr-2"></i> 继续';
        pauseAllBtn.classList.remove('bg-gray-200', 'hover:bg-gray-300');
        pauseAllBtn.classList.add('bg-green-200', 'hover:bg-green-300');
        
        danmakus.forEach(danmakuInfo => {
          if (!danmakuInfo.isPaused) {
            danmakuInfo.pausedAt = Date.now();
            cancelAnimationFrame(danmakuInfo.animationFrame);
            danmakuInfo.element.style.opacity = '0.7';
          }
        });
      } else {
        // 继续所有弹幕
        pauseAllBtn.innerHTML = '<i class="fa fa-pause mr-2"></i> 暂停';
        pauseAllBtn.classList.remove('bg-green-200', 'hover:bg-green-300');
        pauseAllBtn.classList.add('bg-gray-200', 'hover:bg-gray-300');
        
        danmakus.forEach(danmakuInfo => {
          if (!danmakuInfo.isPaused) {
            danmakuInfo.startTime = Date.now() - (danmakuInfo.pausedAt - danmakuInfo.startTime);
            animateDanmaku(danmakuInfo);
            danmakuInfo.element.style.opacity = '1';
          }
        });
      }
    });
    
    // 窗口大小改变时重新计算弹幕位置
    window.addEventListener('resize', () => {
      const containerWidth = danmakuContainer.clientWidth;
      
      danmakus.forEach(danmakuInfo => {
        if (danmakuInfo.isPaused || isPaused) return;
        
        // 取消当前动画
        cancelAnimationFrame(danmakuInfo.animationFrame);
        
        // 计算当前进度
        const currentTime = Date.now();
        const elapsedTime = currentTime - danmakuInfo.startTime;
        const progress = Math.min(elapsedTime / danmakuInfo.animationDuration, 1);
        
        // 重新计算总距离
        const danmakuWidth = danmakuInfo.element.offsetWidth;
        danmakuInfo.totalDistance = containerWidth + danmakuWidth;
        
        // 重新设置开始时间，保持相同进度
        danmakuInfo.startTime = currentTime - (progress * danmakuInfo.animationDuration);
        
        // 重新开始动画
        animateDanmaku(danmakuInfo);
      });
    });
    
    // 自动生成一些示例弹幕
    function generateSampleDanmakus() {
      const samples = [
        "这个弹幕系统好棒啊！",
        "666666",
        "我也来发一条弹幕",
        "大家好呀！",
        "这个设计真不错",
        "前端开发真有趣",
        "学习使我快乐",
        "哈哈哈太好玩了",
        "支持一下！",
        "我是一条测试弹幕"
      ];
      
      const colors = ["#FFFFFF", "#EF4444", "#FBBF24", "#22C55E", "#3B82F6", "#A855F7", "#EC4899"];
      
      // 定时发送示例弹幕
      let index = 0;
      const interval = setInterval(() => {
        if (index >= samples.length || danmakus.length > 0) {
          clearInterval(interval);
          return;
        }
        
        const fontSize = 16 + Math.floor(Math.random() * 10);
        const speed = 8 + Math.floor(Math.random() * 7);
        const color = colors[Math.floor(Math.random() * colors.length)];
        
        createDanmaku(samples[index], fontSize, color, speed);
        addToHistory(samples[index], color);
        
        index++;
      }, 1000);
    }
    
    // 页面加载完成后初始化
    window.addEventListener('load', () => {
      // 自动生成示例弹幕
      generateSampleDanmakus();
      
      // 聚焦输入框
      messageInput.focus();
    });
  </script>
</body>
</html>
